package com.bytz.modules.cms.product.service.impl;

import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.map.MapUtil;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.bytz.common.constant.BooleanConstant;
import com.bytz.common.exception.BytzBootException;
import com.bytz.common.system.query.MPJLambdaWrapperEx;
import com.bytz.common.system.query.MPJQueryGenerator;
import com.bytz.common.util.mentity.EntityMergeInfoV2;
import com.bytz.common.util.mentity.util.MergeEntityOptions;
import com.bytz.common.util.mentity.util.MergeEntityUtil;
import com.bytz.modules.cms.common.util.ExcelUtil;
import com.bytz.modules.cms.product.entity.Product;
import com.bytz.modules.cms.product.entity.ProductEcLicenceUser;
import com.bytz.modules.cms.product.mapper.ProductEcLicenceUserMapper;
import com.bytz.modules.cms.product.model.ProductEcLicenceUserModel;
import com.bytz.modules.cms.product.service.IProductEcLicenceUserService;
import com.bytz.modules.cms.reseller.entity.EndUser;
import com.bytz.modules.cms.reseller.service.IEndUserService;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.util.*;
import java.util.stream.Collectors;

/**
 * <p>
 * 莱宝CMS—产品管理—许可证用户清单表 服务实现类
 * </p>
 *
 * @author KyleWang
 * @since 2022-10-10
 */
@Service
public class ProductEcLicenceUserServiceImpl extends ServiceImpl<ProductEcLicenceUserMapper, ProductEcLicenceUser> implements IProductEcLicenceUserService {

    @Autowired
    private IEndUserService endUserService;

    @Override
    public List<ProductEcLicenceUser> getByCustomerAndProduct(String endUserNumber, List<String> ecProductNumber) {

        if (CollectionUtil.isEmpty(ecProductNumber)) {
            return new ArrayList<>();
        }
        return lambdaQuery()
                .eq(ProductEcLicenceUser::getCustomerNumber, endUserNumber)
                .in(ProductEcLicenceUser::getProductNumber, ecProductNumber)
                .list();
    }


    @Transactional
    @Override
    public List<String> importExcel(List<ProductEcLicenceUser> importData) {
        //进行Excel数据检查
        importData.forEach(this::checkImportData);
        //收集用户ID
        Set<String> customerNumberSet = importData.stream().map(ProductEcLicenceUser::getCustomerNumber).collect(Collectors.toSet());
        //批量导入，由于数据库in有限制，所以500个数据进行导入一次
        List<List<String>> batchCustomerNumbers = CollectionUtil.split(customerNumberSet, 500);
        HashMap<String, String> customerNameMap = MapUtil.newHashMap(customerNumberSet.size());
        for (List<String> queryList : batchCustomerNumbers) {
            List<EndUser> endUsers = endUserService.findByCustomerNumber(queryList);
            endUsers.stream().collect(Collectors.toMap(EndUser::getCustomerNumber, EndUser::getCustomerName, (t1, t2) -> t1, () -> customerNameMap));
        }
        //遍历判断，哪些用户编号存在，哪些用户编号不存在
        Map<Boolean, List<ProductEcLicenceUser>> judgeCustomerNumber = importData.stream().collect(Collectors.groupingBy(p -> customerNameMap.containsKey(p.getCustomerNumber())));
        List<ProductEcLicenceUser> hasCustomerNumber = judgeCustomerNumber.getOrDefault(Boolean.TRUE, Collections.emptyList());
        hasCustomerNumber.forEach(p -> p.setEndUserName(customerNameMap.get(p.getCustomerNumber())));
        List<ProductEcLicenceUser> noCustomerNumber = judgeCustomerNumber.getOrDefault(Boolean.FALSE, Collections.emptyList());
        //封装 未存在的用户
        List<String> missingCustomers = noCustomerNumber.stream().map(ProductEcLicenceUser::getCustomerNumber).collect(Collectors.toList());

        EntityMergeInfoV2<ProductEcLicenceUser> mergeInfo = MergeEntityUtil.calculateEntityMergeInfo(
                importData,
                list(),
                MergeEntityOptions.<ProductEcLicenceUser>builder()
                        .keyExtractor(p -> p.getProductNumber() + "_" + p.getCustomerNumber()).build()
        );
        MergeEntityUtil.doDbMerge(mergeInfo, this);

        return missingCustomers;
    }

    @Override
    public void export(HttpServletResponse response) throws IOException {
        ExcelUtil.export("许可证清单", ProductEcLicenceUser.class, response, list());
    }

    @Override
    public IPage<ProductEcLicenceUserModel> queryPage(Page<ProductEcLicenceUser> page, ProductEcLicenceUserModel productEcLicenceUserModel, Map<String, String[]> requestParams) throws Exception {
        MPJLambdaWrapperEx<ProductEcLicenceUser> wrapper = MPJQueryGenerator.initQueryWrapper(productEcLicenceUserModel, requestParams, ProductEcLicenceUser.class);

        return baseMapper.selectJoinPage(page, ProductEcLicenceUserModel.class, wrapper
                .selectAll(ProductEcLicenceUser.class)
                .select(Product::getMaterialDesc)
                .leftJoin(Product.class, on -> on
                        .eq(Product::getProductNumber, ProductEcLicenceUser::getProductNumber)
                        .eq(Product::getDelFlag, BooleanConstant.INT_FALSE)));
    }


    /**
     * 检查解析后的Excel_List数据
     */
    private void checkImportData(ProductEcLicenceUser ecLinceseUser) {
        if (StringUtils.isBlank(ecLinceseUser.getProductNumber())) {
            throw new BytzBootException("该Excel表里有产品编号未填");
        } else if (StringUtils.isBlank(ecLinceseUser.getCustomerNumber())) {
            throw new BytzBootException("该Excel表里有终端用户编码没有填写");
        }
    }

}
